#include <iostream>
#include <fstream> // 文件流
#include "contacts.pb.h"

void AddPeopleInfo(contacts2::PeopleInfo *people)
{
    std::cout << "--------新增联系人--------" << std::endl;
    std::cout << "请输入姓名：" << std::endl;
    std::string name;
    std::getline(std::cin, name);
    people->set_name(name);
    std::cout << "请输入年龄：" << std::endl;
    int age;
    std::cin >> age;
    people->set_age(age);

    // ignore方法设置：1. 缓冲区清空了，停止
    //                2. 碰到\n，停止
    //                3. 清除256个字符，停止
    // 与后面的设计有关
    std::cin.ignore(256, '\n');
    for (int i = 0;; ++i)
    {
        std::cout << "请输入电话 " << i + 1 << "（只输入回车结束新增）：";
        std::string number;
        std::getline(std::cin, number);
        if (number.empty())
            break;
        contacts2::PeopleInfo_Phone *phone = people->add_phone();
        phone->set_number(number);
        std::cout << "请输入电话类型：1. 移动电话，2. 固定电话" << std::endl;
        int type;
        std::cin >> type;
        std::cin.ignore(256, '\n');// 忽略回车
        switch (type)
        {
            case 1:
                phone->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_MP);
                break;
            case 2:
                phone->set_type(contacts2::PeopleInfo_Phone_PhoneType::PeopleInfo_Phone_PhoneType_TEL);
                break;
            default:
                std::cout << "选择有误！" << std::endl;
                break;
        }
    }
    contacts2::Address address;
    std::cout << "请输入联系人家庭地址：";
    std::string home_address, company_address;
    std::getline(std::cin, home_address);
    address.set_home_address(home_address);
    std::cout << "请输入联系人公司地址：";
    std::getline(std::cin, company_address);
    address.set_company_address(company_address);
    // Address设置进Any，Any可以看作是泛型
    people->mutable_data()->PackFrom(address);
    std::cout << "请选择其他联系方式：1. qq    2. wechat" << std::endl;
    int other;
    std::cin >> other;
    std::cin.ignore(256, '\n');
    if (1 == other) 
    {
        std::cout << "请输入qq号：";
        std::string qq;
        std::getline(std::cin, qq);
        people->set_qq(qq);
    } 
    else if (2 == other)
    {
        std::cout << "请输入wechat：";
        std::string wechat;
        std::getline(std::cin, wechat);
        people->set_wechat(wechat);
    }
    else
    {
        std::cout << "输入有误，未设置其他联系方式" << std::endl;
    }
    for (int i = 0; ; ++i)
    {
        std::cout << "请输入备注" << i + 1 << "标题(只输入回车完成备注新增):";
        std::string remark_key;
        std::getline(std::cin, remark_key);
        if (remark_key.empty())
        {
            break;
        }
        std::cout << "请输入备注" << i + 1 << "内容: ";
        std::string remark_value;
        std::getline(std::cin, remark_value);
        people->mutable_remark()->insert({remark_key, remark_value});
    }
    std::cout << "--------新增联系人成功--------" << std::endl;
}

int main()
{
    contacts2::Contacts contacts;
    // 1. 读取本地已存在的通讯录文件
    // protobuf序列化后的结果是二进制序列
    std::fstream input("contacts.bin", std::ios::in | std::ios::binary);
    if (!input)
    {
        std::cout << "contacts not found, create a new file!" << std::endl;
    }
    else if (!contacts.ParseFromIstream(&input))
    {
        // 反序列化失败
        std::cerr << "parse error!" << std::endl;
        input.close();
        return -1;
    }
    // 2. 添加联系人
    AddPeopleInfo(contacts.add_contacts()); // add_xxx，xxx是Contacs这个message中数组成员名字
    // 3. 保存到本地文件中
    std::fstream output("contacts.bin", std::ios::out | std::ios::trunc | std::ios::binary);
    if (!contacts.SerializeToOstream(&output))
    {
        std::cerr << "write error!" << std::endl;
        input.close();
        output.close();
        return -1;
    }
    std::cout << "write success!" << std::endl;
    input.close();
    output.close();
    return 0;
}